package com.usian.comment.service.impl;

import com.usian.comment.feign.ApUserFeign;
import com.usian.comment.service.CommentService;
import com.usian.model.comment.dtos.CommentDto;
import com.usian.model.comment.dtos.CommentLikeDto;
import com.usian.model.comment.dtos.CommentSaveDto;
import com.usian.model.comment.pojos.ApComment;
import com.usian.model.comment.pojos.ApCommentLike;
import com.usian.model.comment.vo.ApCommentVo;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.user.pojos.ApUser;
import com.usian.utils.threadlocal.UserIdThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.usian.model.common.enums.AppHttpCodeEnum.*;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ApUserFeign apUserFeign;


    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {

        if (dto == null) return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        if (dto.getChannelId() == null && dto.getArticleId() == null && dto.getContent() == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        Integer userId = UserIdThreadLocalUtils.getUserId();
        if (userId == null) return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        ApUser apUser = apUserFeign.findUserById(userId);
        if (apUser == null) return ResponseResult.errorResult(USER_NOT_EXIST);
        ApComment apComment = new ApComment();
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setEntryId(dto.getArticleId());
        apComment.setChannelId(Integer.parseInt(dto.getChannelId()));
        apComment.setType((short) 0);
        apComment.setContent(dto.getContent());
        apComment.setImage(apUser.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setFlag((short) 0);
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        mongoTemplate.insert(apComment);


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult like(CommentLikeDto dto) {

        if (dto == null) return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        if (dto.getCommentId() == null && dto.getOperation() == null)return ResponseResult.errorResult("评论id和行为不能为空");
        if (dto.getOperation() != 0 && dto.getOperation() != 1) return ResponseResult.errorResult("点赞传参错误");
        Integer userId = UserIdThreadLocalUtils.getUserId();
        if (userId == null) return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        ApUser apUser = apUserFeign.findUserById(userId);
        if (apUser == null) return ResponseResult.errorResult(USER_NOT_EXIST);
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment == null) return ResponseResult.errorResult(DATA_NOT_EXIST);

        ApCommentLike apCommentLike = new ApCommentLike();
        apCommentLike.setCommentId(dto.getCommentId());
        apCommentLike.setAuthorId(userId);
        if (dto.getOperation() == 0) {
            ApCommentLike one = mongoTemplate.findOne(Query.query(Criteria.where("authorId").is(userId).and("commentId").is(apComment.getId())), ApCommentLike.class);
            if (one != null)return ResponseResult.errorResult("点赞完成");
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);
            apComment.setLikes(apComment.getLikes() + 1);
        } else {
            mongoTemplate.remove(Query.query(Criteria.where("authorId").is(userId).and("commentId").is(apComment.getId())),ApCommentLike.class);
            apComment.setLikes(apComment.getLikes() > 0 ? apComment.getLikes() - 1 : 0);

        }
        mongoTemplate.save(apComment);
        //5.数据返回
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", apComment.getLikes());
        return ResponseResult.okResult(resultMap);
    }


    /*
    * 查询评论列表，根据当前文章id进行检索，按照创建时间倒序，分页查询（默认10条数据）
        实现思路
        1）按照文章id过滤，设置分页和排序 按照前台传递过来的最小时间判断分页时机
        2）用户未登录 直接返回评论列表数据
        3）用户已登录，需要判断当前用户点赞了哪些评论，标记点赞的评论
    * */
    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        if (dto == null) return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        if (dto.getArticleId() == null )return ResponseResult.errorResult("文章id不能为空");
        if (dto.getMinDate() == null)dto.setMinDate(new Date());
        Integer userId = UserIdThreadLocalUtils.getUserId();

        //根据
        List<ApComment> apComments = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate())).
                limit(dto.getSize()).with(Sort.by(Sort.Direction.DESC,"createdTime")), ApComment.class);

        if (userId == null)return ResponseResult.okResult(apComments);

        List<String> listId = new ArrayList<>();
        apComments.forEach(ids->{
            listId.add(ids.getId());
        });

        //List<String> idList = apComments.stream().map(x -> x.getId()).collect(Collectors.toList());

        //查询所有
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(Query.query(Criteria.where("authorId").is(userId).and("commentId").in(listId)), ApCommentLike.class);

        List<ApCommentVo> resultList = new ArrayList<>();

        apComments.forEach(x -> {
            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(x, apCommentVo);
            for (ApCommentLike apCommentLike : apCommentLikes) {
                if (x.getId().equals(apCommentLike.getCommentId())) {
                    apCommentVo.setOperation((short) 0);
                    break;
                }
            }
            resultList.add(apCommentVo);
        });

        return ResponseResult.okResult(resultList);
    }
}
